// Learn cc.Class:
//  - [Chinese] http://docs.cocos.com/creator/manual/zh/scripting/class.html
//  - [English] http://www.cocos2d-x.org/docs/creator/en/scripting/class.html
// Learn Attribute:
//  - [Chinese] http://docs.cocos.com/creator/manual/zh/scripting/reference/attributes.html
//  - [English] http://www.cocos2d-x.org/docs/creator/en/scripting/reference/attributes.html
// Learn life-cycle callbacks:
//  - [Chinese] http://docs.cocos.com/creator/manual/zh/scripting/life-cycle-callbacks.html
//  - [English] http://www.cocos2d-x.org/docs/creator/en/scripting/life-cycle-callbacks.html
var Utils = require("./Utils.js");

let MSG_TYPE = {
    CHOOSE_SERVER: "CHOOSE_SERVER",//判定谁是server
    TEST_CONNECTION: "TEST_CONNECTION",//探测连接
    SYNC_DATA: "SYNC_DATA", //server同步数据给client
    HEART_BEAT: "HEART_BEAT",//心跳包
    FOR_PEACE: "FOR_PEACE",//求和
    FOR_DEFEAT: "FOR_DEFEAT",//认输
    AGREE_DEFEAT: "AGREE_DEFEAT",//同意求和
    REFUSE_DEFEAT: "REFUSE_DEFEAT",//拒绝求和
    EXIT: "EXIT",//退出游戏
}

let GAME_RESULT = {
    DRAWN: 0,
    VICTORY: 1,
    DEFEAT: 2
};
const crypto = require('crypto');
let ROBEOT = 9;

cc.Class({
    extends: cc.Component,

    properties: {
        selfIconNode: cc.Node,
        rivalIconNode: cc.Node,
        selfNameLable: cc.Label,
        rivalNameLable: cc.Label,
        rulePrefab: {
            type: cc.Prefab,
            default: null
        },
        readyGoPrefab: {
            type: cc.Prefab,
            default: null
        },

        backgroundAudio: {
            url: cc.AudioClip,
            default: null
        },

        readyGoAudio: {
            url: cc.AudioClip,
            default: null
        },

        background: {
            default: null,
            type: cc.Node
        },

        selfSexNode: {
            default: null,
            type: cc.Node,
        },

        rivalSexNode: {
            default: null,
            type: cc.Node,
        },

        guidePrefab: cc.Prefab,

        showRule: {
            default: true,
            type: cc.Boolean
        },


    },

    ctor() {

        console.log("BaseGame ctor");

        this.gameResult = -1;
        this.isSceneEnd = false; //只打开场景一次

  

        this.serverJudged = false;

        this.chooseServerRandom = -1;
        this.rivalChooseServerRandom = -1;

        cc.gameMounted = this.gameMounted.bind(this);
        cc.exit = this.nativeExit.bind(this);

        //注册全局声音接口
        // Global.audioOpen = true;
        cc.mzOpenAudio = this.mzOpenAudio.bind(this);
        cc.mzPlayAudio = this.mzPlayAudio.bind(this);
        cc.mzCloseAudio = this.mzCloseAudio.bind(this);
        cc.mzOpenRule = this.mzOpenRule.bind(this);
        cc.mzCloseRule = this.mzCloseRule.bind(this);
        cc.toast = this.toast.bind(this);

        cc.mzForPeace = this.mzForPeace.bind(this);
        cc.mzEnsurePeace = this.mzEnsurePeace.bind(this);
        cc.mzRefusePeace = this.mzRefusePeace.bind(this);
        cc.victory = this.victory.bind(this);
        cc.drawn = this.drawn.bind(this);
        cc.defeat = this.defeat.bind(this);
        cc.ensureGiveUp = this.ensureGiveUp.bind(this);

        cc.game.on(cc.game.EVENT_HIDE, this.onGameHide.bind(this));
        cc.game.on(cc.game.EVENT_SHOW, this.onGameShow.bind(this));



        let exited = false;
    },

    onLoad(){
        let frameSize = cc.director.getOpenGLView().getFrameSize();
        let rate = frameSize.height / frameSize.width;
        if(rate < 16 / 9){
            var canvas = this.node.getComponent(cc.Canvas);
            canvas.fitHeight = true;
            canvas.fitWidth = false;
            cc.log("fit height");
        }
    },

    //子类重写，必须 调用this._super(), 通知android层cocos已经准备好
    start() {
        this.destroyed = false;
        //注册pomelo监听，必须放在start里面，不然被反注册了无法使用
        pomelo.on("onGameChat", this.onRivalMessage.bind(this));
        // pomelo.on("onRoomMemberChange", this.onRoomMemberChange.bind(this));
        // pomelo.on('disconnect', this.onDisconnect.bind(this));
        // pomelo.on('heartbeat timeout', this.onDisconnect.bind(this));
        pomelo.on("onGameOver", this.gameOver.bind(this));
        // pomelo.on("onLeaveWithoutOnline", this.onLeaveWithoutOnline.bind(this));
        // pomelo.on("onForceOffline", this.onForceOffline.bind(this));
        console.log("BaseGame start");

        cc.systemEvent.on(cc.SystemEvent.EventType.KEY_DOWN, (event) => {
            cc.log("on KEY_DOWN event.keyCode ="+event.keyCode);
            if (event.keyCode == cc.KEY.back) {
                if (this.ruleNode) {
                    this.mzCloseRule();
                    return true;
                } else {
                    //this.forGiveUp(); back后退到后台不弹出认输弹框
                }
            }
            return false;
        }, this);


        this.physicsManager = cc.director.getPhysicsManager();
        // if (this.isAndroid()) {
        //     cc.log("onGameLoaded");
        //     jsb.reflection.callStaticMethod("com/meizu/play/quickgame/activity/GameActivity", "onGameLoaded", "(Z)V", this.showRule);

        // } else {
        // }

        let matchNode = cc.director.getScene().getChildByName("match_node");
        let data =  matchNode.getComponent("ResultData").getData();
        cc.log("getResultData data =" + data.toString());

        this.gameMounted(data.token,
            data.game,data.room,data.selfInfo,data.friendInfo,data.imei);
    },

    onDestroy() {
        console.log("游戏场景被销毁");
        this.destroyed = true;
        pomelo.removeAllListeners();
        clearTimeout(this.toGameRoomTimeout);
    },

    //由android调用，初始化信息
    gameMounted(token, gameId, roomId, selfInfo,friendInfo, imei) {
        this.mounted = true;

        this.rivalIsRobot = false;

        let self = this;
        self.myUserInfo = selfInfo;
        self.rivalUserInfo = friendInfo;
        if (self.rivalUserInfo.type == ROBEOT) {
            self.rivalIsRobot = true;
        }

        if (!self.myUserInfo) {
            cc.log("can not find userInfo in userInfos with userId");
        }

        this.onUserInfos(this.myUserInfo, this.rivalUserInfo);
        
        if (this.rivalIsRobot && !this.gameStarted) {
            //如果对手是机器人，则跳过流程，直接判定自己为server
            this.chooseServerRandom = 10;
            this.rivalChooseServerRandom = 9;
            this.beServer();
        }

        this.onPrepare();
    },

    onPrepare() {
    },

    setSex(node, sex) {
        if (node) {
            let url = "Texture/sex/female";
            if (sex == 1) {
                //男性
                url = "Texture/sex/male";
            }
            cc.loader.loadRes(url, cc.SpriteFrame, function (err, spriteFrame) {
                if (err) {
                    cc.log(err);
                } else {
                    node.getComponent(cc.Sprite).spriteFrame = spriteFrame;
                }
            }.bind(this));
        }

    },

    //由子类继承，在界面呈现用户信息
    onUserInfos(selfUserInfo, rivalUserInfo) {
        let self = this;
        let types = ['png', 'jpg'];
        // if (this.isAndroid()) {
            if (selfUserInfo) {
                console.log("创建游戏中自己的头像 icon ="+selfUserInfo.icon);
                types.forEach((type) => {
                    cc.loader.load({ url: selfUserInfo.icon, type: type }, function (err, texture) {
                        if (!err) {
                            console.log("self icon loaded, type:" + type);

                            var w = self.selfIconNode.width;
                            var h = self.selfIconNode.height;
                            var frame = new cc.SpriteFrame(texture);
                            self.selfIconNode.getComponent(cc.Sprite).spriteFrame = frame;
                            self.selfIconNode.width = w;
                            self.selfIconNode.height = h;
                        } else {
                            console.log("load img , error:" + err);
                        }
                    });
                });
            }

            if (rivalUserInfo) {
                types.forEach((type) => {
                    cc.loader.load({ url: rivalUserInfo.icon, type: type }, function (err, texture) {
                        if (!err) {
                            console.log("BaseGame rival icon loaded, icon:" + rivalUserInfo.icon);
                            if(self.rivalIconNode) {
                                var w = self.rivalIconNode.width;
                                var h = self.rivalIconNode.height;
                                var frame = new cc.SpriteFrame(texture);
                                self.rivalIconNode.getComponent(cc.Sprite).spriteFrame = frame;
                                self.rivalIconNode.width = w;
                                self.rivalIconNode.height = h;
                            }
                        } else {
                            cc.log("load img , error:" + err);
                        }
                    });
                });
            }

        // }

        this.setSex(this.rivalSexNode, rivalUserInfo.gender);
        this.setSex(this.selfSexNode, selfUserInfo.gender);

    },

    /**
     * server断开重新连接后，同步数据给client
     * client断开连接重新连接后，请求server同步数据过来
     */
    syncData() {

    },

    //获取当前游戏实时数据
    getGameData() {

    },

    //接受对手消息, 子类重写， 调用this._super(), 返回false时，处理没有被消费的消息
    onRivalMessage(msg) {
        let data = JSON.parse(msg.msg);
        cc.log("receive msg:");
        cc.log(msg);
        if(this.exited) {
            return false;
        }

        switch (data.type) {
            case MSG_TYPE.CHOOSE_SERVER:
                //对手发送过来判定server的随机值
                this.rivalChooseServerRandom = data.random;
                this.beServer();
                return true;
            case MSG_TYPE.SYNC_DATA:
                //由server发给client
                cc.log("receive gameData");
                cc.log(data.gameData);
                this.loadGame(data.gameData);
                cc.log("game started");
                return true;
            case MSG_TYPE.FOR_PEACE:
                this.withPeaceDialog();
                return true;
            case MSG_TYPE.AGREE_DEFEAT:
                this.toast("对手同意求和");
                this.drawn();
                return true;
            case MSG_TYPE.REFUSE_DEFEAT:
                this.toast("对手没有接受求和，游戏继续");
                return true;
            case MSG_TYPE.EXIT:
                this.toast("对方已经溜了");
                this.exit();
                return true;
            default:
                return false;
        }
    },


    //判定自己是server， 还是对手是server
    beServer() {
        cc.log("beServer");
        if (this.chooseServerRandom >= 0 && this.rivalChooseServerRandom >= 0) {
            //自己的rand已经生成，并且接受到对手的random
            if (this.chooseServerRandom > this.rivalChooseServerRandom) {
                this.isServer = true;
                cc.log("server");

                let gameData = this.onGenerateGameData();
                cc.log("generate gameData");
                this.loadGame(gameData);

                cc.log("game started");
            } else {
                this.isServer = false;
                cc.log("client");
            }
        }
    },

    //玩家连接完毕，游戏准备前， 由子类实现，可在其中做一些游戏准备开始的动画, 需要调用super
    readyGo() {
        this.needGuide = true;
        if (cc.sys.localStorage.getItem("havePlayYet" + "_" + this.gameId) == "true") {
            this.needGuide = false;
        } else {
            cc.sys.localStorage.setItem("havePlayYet" + "_" + this.gameId, true);
        }

        let  readyGoNode = cc.instantiate(this.readyGoPrefab);
        let readyGoScript = readyGoNode.getComponent("ReadyGo");
        this.node.addChild(readyGoNode);
        
        setTimeout(function () {
            readyGoScript.play();
            this.mzPlayAudio(this.readyGoAudio);
        }.bind(this), 1000);
        // this.mzPlayAudio(this.backgroundAudio, true);

        // if (this.isAndroid()) {
        //     cc.log("readyGo");
        //     jsb.reflection.callStaticMethod("com/meizu/play/quickgame/activity/GameActivity", "readyGo", "()V");

        // } else {
        // }
    },

    //由子类继承， 必须通过调用this._super()拿到结果后，继续填充数据
    onGenerateGameData() {
        //server生成游戏数据， client接受游戏数据
        return {};
    },

    //获取当前游戏所有数据, 以用于同步重新连接时的游戏数据
    onGetGameData() {
        return {};
    },

    //根据游戏数据加载游戏, 必须调用this._super()
    loadGame(gameData) {
        this.gameStarted = true;
        this.readyGo();
        this.onGameStart();

        if (this.rivalIsRobot) {
            this.robotGameStart();
        }
    },

    //游戏数据加载完毕有，开始游戏
    onGameStart() {

    },

    sendMessage(msg){

    },

    //开始模拟机器人
    robotGameStart() {

    },

    reportResult(victory, type, callback) {
        if (!this.reported) {
            cc.log("report result:" + victory);
            var route = "chat.gameHandler.overNew";
            this.victoryed = victory;
            this.reported = true;
            let time = parseInt(Date.now() / 1000);
            let uids = this.victoryed ? [this.myUserInfo.id, this.rivalUserInfo.id] : [this.rivalUserInfo.id, this.myUserInfo.id];
            pomelo.request(route, {
                room: this.roomId,
                uids: uids,
                ranks: "1,2",
                scores: "0,0",//得分or时间
                type: type, //2：认输结束，1：正常结束，-1：异常结束
                room: this.roomId,
                game: this.gameId,
                time:time,
                sign:crypto.createHash('md5').update("" + uids + "1,2" + time, 'utf8').digest("hex") //uids+scores+time
            }, function (data) {
                console.log(data);
                if (callback) callback();
            });
        }
    },

    //平局
    drawn(type = 1) {
        this.gameResult = GAME_RESULT.DRAWN;
        this.overed = true;
        cc.log("drawn: 平局");

        let matchNode = cc.director.getScene().getChildByName("match_node");
        let data = matchNode.getComponent("ResultData").getData();
        data.drawn = true
        matchNode.getComponent("ResultData").init(data);
        this.sceneEnd();
    },


    //我方胜利，向服务端报告, 默认正常结束
    victory(type = 1) {
        this.overed = true;
        this.gameResult = GAME_RESULT.VICTORY;
        
        let matchNode = cc.director.getScene().getChildByName("match_node");
        let data = matchNode.getComponent("ResultData").getData();
        data.victory = true
        matchNode.getComponent("ResultData").init(data);
        this.sceneEnd();

        cc.log("victory:true");
    },

    //我方失败，向服务端报告
    defeat(type = 1) {
        this.gameResult = GAME_RESULT.DEFEAT;
        this.overed = true;
        let matchNode = cc.director.getScene().getChildByName("match_node");
        let data = matchNode.getComponent("ResultData").getData();
        data.defeat = true
        matchNode.getComponent("ResultData").init(data);
        this.sceneEnd();

        cc.log("victory:false");
    },

    /**
     * 认输
     */
    // forGiveUp() {
    //     cc.log("认输");
    //     if (this.isAndroid()) {
    //         jsb.reflection.callStaticMethod("com/meizu/play/quickgame/activity/GameActivity", "forGiveUp", "()V");
    //     } else {
    //     }
    // },

    //求和弹框
    forPeaceDialog() {
        cc.log("弹出求和弹框");
        if (this.haveForPeace) {
            Utils.showMzGameToast("本回合仅可发起一次求和");
        } else {
            cc.log("求和");
            Alert.show("确定发起求和","取消","确定", this.mzForPeace.bind(this), true, 0);
        }
    },

    //确认发起求和
    mzForPeace() {
        cc.log("确认发起求和");
        if (this.haveForPeace) {
            Utils.showMzGameToast("本回合仅可发起一次求和");
        } else {
            this.haveForPeace = true;
            this.sendMessage({ type: MSG_TYPE.FOR_PEACE });
            this.toast("等待对手回复");
            if (this.rivalIsRobot) {
                //机器人始终拒绝求和
                setTimeout(function () {
                    if(Math.random() * 2 > 1){
                        this.toast("对手没有接受求和，游戏继续");
                    }else{
                        this.toast("对手同意求和");
                        this.drawn();
                    }
                    
                }.bind(this), Math.floor((Math.random() * 2) + 1) * 1000);
            }
        }
    },

    //对手求和
    withPeaceDialog() {
        cc.log("求和");
        // if (this.isAndroid()) {
        //     jsb.reflection.callStaticMethod("com/meizu/play/quickgame/activity/GameActivity", "withPeace", "()V");
        // } else {
        // }
        Alert.showCountDownDialog("是否接受对手求和","接受","拒绝", this.mzRefusePeace.bind(this), 
        this.mzEnsurePeace.bind(this), true, 0, true, 5, this);
    },

    //确认同意求和
    mzEnsurePeace() {
        cc.log("同意求和");
        this.sendMessage({ type: MSG_TYPE.AGREE_DEFEAT });
        this.drawn(0); 
    },

    //拒绝求和
    mzRefusePeace() {
        cc.log("拒绝求和");
        this.sendMessage({ type: MSG_TYPE.REFUSE_DEFEAT });
    },


    /**
     * 认输
     */
    forGiveUp() {
        cc.log("认输");
        // if (this.isAndroid()) {
        //     jsb.reflection.callStaticMethod("com/meizu/play/quickgame/activity/GameActivity", "forGiveUp", "()V");
        // } else {
        // }
        // if(Utils.isAndroid()) {
            cc.log("showDialog");
            // new Meizu.MzGame().showDialog("退出你就输啦", "在下认输", "我要继续",this.ensureGiveUp(),null);
            Alert.show("退出你就输了","我要继续","在下认输", this.ensureGiveUp.bind(this), true, 0);
        // }
    },

    /**
     * 确认认输
     */
    ensureGiveUp() {
        cc.log("ensureGiveUp");
        this.defeat(2);
    },

    //服务器判定游戏结束, 需要调用super
    gameOver(data) {
        cc.log("game over data ="+JSON.stringify(data));
        for(let i = 0;i < data.uids.length ; i++) {
            cc.log("gameOver 当前 id  =:" + data.uids[i]);
            cc.log("gameOver myUserInfo  =:" + this.myUserInfo.id);
            cc.log("gameOver friendInfo  =:" + this.rivalUserInfo.id);

            if( data.uids[i] != this.myUserInfo.id &&  data.uids[i] != this.rivalUserInfo.id) {
                cc.log("gameOver 当前游戏不存在的id  =:" +  data.uids[i]);
                return;
            }
        }
        if (!this.reported ) {
            //非自己上报
            if (data.uids.length >= 1 && data.uids[0] == this.myUserInfo.id) {
                this.victoryed = true;
            } else {
                this.victoryed = false;
            }
            cc.log("victory:" + this.victoryed);
            this.sceneEnd();
        }
    },

    //游戏界面关闭， 展示游戏结果
    sceneEnd() {
        cc.log("游戏界面关闭，展示游戏结果");
        clearTimeout(this.gameExitTimer);       //清除游戏exit超时倒计时
        this.exited = true;
        if(!this.isSceneEnd) {
            this.isSceneEnd = true;
            cc.director.loadScene("game_over");
        }
        // if (this.isAndroid()) {
        //     jsb.reflection.callStaticMethod("com/meizu/play/quickgame/activity/GameActivity", "onGameOver", "(Z)V", this.victoryed);
        // } else {
        //     cc.director.end();
        // }
    },

    //游戏异常退出
    exit() {
        this.exited = true;
        pomelo.disconnect();
        setTimeout(function () {
            cc.director.loadScene("mz_game_main");
        }.bind(this), 2000);
    },

    //android端调用退出
    nativeExit() {
        if (this.gameStarted) {
            this.defeat();
        } else {
            this.exit();
        }

    },

    //对方10秒没有上线
    onLeaveWithoutOnline() {
        cc.log("对方已经离开");
        // this.victory();
    },

    isAndroid() {
        return Utils.isAndroid();
    },

    toast(str) {
        Utils.showMzGameToast(str);
        // cc.log("toast:" + str);
        // if (this.isAndroid()) {
        //     Utils.showMzGameToast(str);
        //     //jsb.reflection.callStaticMethod("com/meizu/play/quickgame/activity/GameActivity", "toast", "(Ljava/lang/String;)V", str);
        // } else {
        // }
    },

    mzCloseAudio() {
        cc.audioEngine.pauseAllEffects();
        cc.audioEngine.stopMusic();
    },

    mzOpenAudio() {
        if (!cc.audioEngine.isMusicPlaying() && this.backgroundAudio) {
            cc.audioEngine.playMusic(this.backgroundAudio, true);
        }
    },



    mzPlayAudio(audioClip, loop = false) {
        if (audioClip) {            if (this.backgroundAudio == audioClip && this.backgroundAudio) {
                if (!cc.audioEngine.isMusicPlaying()) {
                    return cc.audioEngine.playMusic(audioClip, loop);
                }
            } else {
                return cc.audioEngine.play(audioClip, loop);
            }

        }
    },

    mzOpenRule() {
        cc.log("mzOpenRule");
        if (this.ruleNode && this.ruleNode.isValid) {
            cc.log("不能打开两次");
        } else {
            this.ruleNode = cc.instantiate(this.rulePrefab);
            this.ruleNode.x = 0;
            this.ruleNode.y = 0;
            this.node.addChild(this.ruleNode);
        }

    },

    mzCloseRule() {
        cc.log("mzCloseRule");
        this.ruleNode.destroy();
        this.ruleNode = null;
    },

    //游戏切换到后台
    onGameHide() {
        cc.log("切换到后台");
        this.hide = true;
        this.hideTime = new Date().getTime() / 1000;
    },

    //游戏重新切换到前台
    onGameShow() {
        if (this.hide) {
            this.onSkipTime(new Date().getTime() / 1000 - this.hideTime);
            this.hide = false;
        }
    },

    //由于多任务，和home， 导致的游戏暂停，漏掉的时间
    onSkipTime(time) {

    }

});
